package tr.edu.ege.seagent.hobnobontology.instance;

import org.apache.jena.fuseki.DatasetAccessor;
import org.apache.jena.fuseki.DatasetAccessorFactory;

import tr.edu.ege.seagent.hobnobontology.schema.HobNobVocabulary;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;

/**
 * @author etmen
 * 
 */
public class HobNobHandleRDFDataOverHttp {

	public static final String GRAPH_STORE_READ_WRITE = "http://localhost:3030/ds/data";

	private DatasetAccessor accessor;

	private HobNobInstanceCreator creator;
	private Model model;

	public HobNobHandleRDFDataOverHttp() {
		this.model = ModelFactory.createDefaultModel();
		this.accessor = DatasetAccessorFactory
				.createHTTP(GRAPH_STORE_READ_WRITE);
		this.creator = new HobNobInstanceCreator(this.model);
	}

	/**
	 * This function provide us to create cafe pi notification statements.
	 * 
	 * @return {@link HobNobHandleRDFDataOverHttp#model} with form of cafe pi
	 *         notification statements are added.
	 * 
	 */
	private void createCafePiNotificationStatements() {
		// creates instance...
		creator.createInstance(
				HobNobInstanceVocabulary.NOTIFICATION_CAFE_PI_URI,
				HobNobVocabulary.NOTIFICATION_URI);

		// creates notification has member statement that between notification
		// cafe pi and member bahti...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_CAFE_PI_URI,
				HobNobInstanceVocabulary.MEMBER_BAHTI_URI);
		// creates notification has member statement that between notification
		// cafe pi and member ceren...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_CAFE_PI_URI,
				HobNobInstanceVocabulary.MEMBER_CEREN_URI);
		// creates notification at location statement that between notification
		// cafe pi and location cafe pi...
		createNotificationAtLocation(creator,
				HobNobInstanceVocabulary.NOTIFICATION_CAFE_PI_URI,
				HobNobInstanceVocabulary.LOCATION_CAFE_PI_URI);
		// creates notification message statement that between notification
		// cafe pi and message cafe pi...
		createNotificationMessage(creator,
				HobNobInstanceVocabulary.NOTIFICATION_CAFE_PI_URI,
				HobNobSampleModelCreator.MSG_CAFEPI_NOTIFICATION);

	}

	/**
	 * This function provide us to create istanbul notification statements.
	 * 
	 * @return {@link HobNobHandleRDFDataOverHttp#model} with form of istanbul
	 *         notification statements are added.
	 */
	private void createIstanbulNotificationStatements() {

		// creates instance...
		creator.createInstance(
				HobNobInstanceVocabulary.NOTIFICATION_ISTANBUL_URI,
				HobNobVocabulary.NOTIFICATION_URI);
		// creates notification has member statement that between notification
		// istanbul and member bahti...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_ISTANBUL_URI,
				HobNobInstanceVocabulary.MEMBER_BAHTI_URI);
		// creates notification has member statement that between notification
		// istanbul and member ceren...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_ISTANBUL_URI,
				HobNobInstanceVocabulary.MEMBER_CEREN_URI);
		// creates notification at location statement that between notification
		// istanbul and location istanbul...
		createNotificationAtLocation(creator,
				HobNobInstanceVocabulary.NOTIFICATION_ISTANBUL_URI,
				HobNobInstanceVocabulary.LOCATION_ISTANBUL_URI);
		// creates notification message statement that between notification
		// istanbul and message istanbul...
		createNotificationMessage(creator,
				HobNobInstanceVocabulary.NOTIFICATION_ISTANBUL_URI,
				HobNobTDBStore.MSG_ISTANBUL_NOTIFICATION);

	}

	/**
	 * This function provide us to create seagent notification statements.
	 * 
	 * @return {@link HobNobHandleRDFDataOverHttp#model} with form of seagent
	 *         notification statements are added.
	 */
	private void createSeagentNotificationStatements() {

		// creates instance...
		creator.createInstance(
				HobNobInstanceVocabulary.NOTIFICATION_SEAGENT_URI,
				HobNobVocabulary.NOTIFICATION_URI);
		// creates notification has member statement that between notification
		// seagent and member bahti...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_SEAGENT_URI,
				HobNobInstanceVocabulary.MEMBER_BAHTI_URI);
		// creates notification has member statement that between notification
		// seagent and member tayfun...
		createNotificationHasMemberStatement(creator,
				HobNobInstanceVocabulary.NOTIFICATION_SEAGENT_URI,
				HobNobInstanceVocabulary.MEMBER_TAYFUN_URI);
		// creates notification at location statement that between notification
		// seagent and location seagent...
		createNotificationAtLocation(creator,
				HobNobInstanceVocabulary.NOTIFICATION_SEAGENT_URI,
				HobNobInstanceVocabulary.LOCATION_SEAGENT_URI);
		// creates notification message statement that between notification
		// seagent and message seagent...
		createNotificationMessage(creator,
				HobNobInstanceVocabulary.NOTIFICATION_SEAGENT_URI,
				HobNobSampleModelCreator.MSG_SEAGENT_NOTIFICATION);

	}

	/**
	 * This function provide us to create notification statements and put the
	 * model that includes this created statements to the TDB store over http.
	 * 
	 */
	public void putNotificationStatementsToTDBOverHttp() {
		// puts seagent notification statements to TDB Store over Http...
		createSeagentNotificationStatements();
		// puts istanbul notification statements to TDB Store over Http...
		createIstanbulNotificationStatements();
		// puts cafe-pi notification statements to TDB Store over Http...
		createCafePiNotificationStatements();

		accessor.add(model);
	}

	/**
	 * This function provide us to create location statement which is related
	 * with given notification URI.
	 * 
	 * @param creator
	 *            {@link HobNobInstanceCreator} about creation of new model.
	 * @param notificationURI
	 *            URI of notification.
	 * @param locationURI
	 *            URI of location.
	 */
	private void createNotificationAtLocation(HobNobInstanceCreator creator,
			String notificationURI, String locationURI) {

		creator.createResourceStatement(notificationURI,
				HobNobVocabulary.NOTIFICATION_AT_LOCATION_URI, locationURI);

	}

	/**
	 * This function provide us to create member statement which is related with
	 * given notification URI
	 * 
	 * @param creator
	 *            {@link HobNobInstanceCreator} about creation of new model.
	 * @param notificationURI
	 *            URI of notification.
	 * @param memberURI
	 *            URI of member.
	 */
	private void createNotificationHasMemberStatement(
			HobNobInstanceCreator creator, String notificationURI,
			String memberURI) {

		creator.createResourceStatement(notificationURI,
				HobNobVocabulary.NOTIFICATION_HAS_MEMBER_URI, memberURI);

	}

	/**
	 * This function provide us to create
	 * {@link HobNobVocabulary#NOTIFICATION_MESSAGE_URI} property statement.
	 * 
	 * @param creator
	 *            {@link HobNobInstanceCreator} about creation of new model.
	 * @param notificationURI
	 *            URI of notification.
	 * @param notificationMessage
	 *            literal value.
	 */
	private void createNotificationMessage(HobNobInstanceCreator creator,
			String notificationURI, String notificationMessage) {

		creator.createLiteralStatement(notificationURI,
				HobNobVocabulary.NOTIFICATION_MESSAGE_URI, notificationMessage);

	}

	/**
	 * This function provide us to create member statements and put the model
	 * that includes this created statements to the TDB store over http.
	 */
	public void putMemberStatementsToTDBOverHttp() {
		// creates statements which are related with member bahti...
		createMemberBahtiStatements();
		// creates statements which are related with member ceren...
		createMemberCerenStatements();
		// creates statements which are related with member tayfun...
		createMemberTayfunStatements();

		accessor.add(model);

	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#MEMBER_TAYFUN_URI} statements.
	 */
	private void createMemberTayfunStatements() {

		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobVocabulary.MALE_URI);
		// creates name literal statement of member...
		createMembersName(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobInstanceVocabulary.TAYFUN_NAME);
		// creates surname literal statement of member...
		createMembersSurname(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobInstanceVocabulary.TAYFUN_SURNAME);
		// creates e-mail literal statement of member...
		createMembersEMail(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobInstanceVocabulary.TAYFUN_EMAIL);
		// creates phone literal statement of member...
		createMembersPhone(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobInstanceVocabulary.TAYFUN_PHONE);
		// creates language literal statement of member...
		createMembersLanguage(HobNobInstanceVocabulary.MEMBER_TAYFUN_URI,
				HobNobInstanceVocabulary.LANGUAGE_ENGLISH);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#MEMBER_CEREN_URI} statements.
	 */
	private void createMemberCerenStatements() {

		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobVocabulary.FEMALE_URI);
		// creates name literal statement of member...
		createMembersName(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.CEREN_NAME);
		// creates surname literal statement of member...
		createMembersSurname(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.CEREN_SURNAME);
		// creates e-mail literal statement of member...
		createMembersEMail(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.CEREN_EMAIL);
		// creates phone literal statement of member...
		createMembersPhone(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.CEREN_PHONE);
		// creates language literal statement of member...
		createMembersLanguage(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.LANGUAGE_ENGLISH);
		// creates friend resource statement of member...
		createFriendOfMember(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.MEMBER_BAHTI_URI);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#MEMBER_BAHTI_URI} statements.
	 */
	private void createMemberBahtiStatements() {
		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobVocabulary.MALE_URI);
		// creates name literal statement of member...
		createMembersName(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.BAHTI_NAME);
		// creates surname literal statement of member...
		createMembersSurname(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.BAHTI_SURNAME);
		// creates e-mail literal statement of member...
		createMembersEMail(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.BAHTI_EMAIL);
		// creates phone literal statement of member...
		createMembersPhone(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.BAHTI_PHONE);
		// creates language literal statement of member...
		createMembersLanguage(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.LANGUAGE_ENGLISH);
		// creates friend resource statement of member...
		createFriendOfMember(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.MEMBER_CEREN_URI);
	}

	/**
	 * This function provide us to create member's resource statement with using
	 * {@link HobNobVocabulary#FRIEND_URI} property
	 * 
	 * @param memberURI
	 *            URI of member.
	 * @param friendURI
	 *            URI of member.
	 */
	private void createFriendOfMember(String memberURI, String friendURI) {
		creator.createFriendOfMember(memberURI, HobNobVocabulary.FRIEND_URI,
				friendURI);
	}

	/**
	 * This function provide us to create member statement with using language
	 * of member.
	 * 
	 * @param memberURI
	 *            URI of member.
	 * @param language
	 *            literal value.
	 */
	private void createMembersLanguage(String memberURI, String language) {
		creator.createLanguageLiteral(memberURI, HobNobVocabulary.LANGUAGE_URI,
				language);
	}

	/**
	 * This function provide us to create member statement with member's phone
	 * number.
	 * 
	 * @param memberURI
	 *            URI of member.
	 * @param phone
	 *            literal value.
	 */
	private void createMembersPhone(String memberURI, String phone) {
		creator.createLiteralStatement(memberURI,
				HobNobVocabulary.PHONE_NUMBER_URI, phone);
	}

	/**
	 * This function provide us to create member literal statement with member's
	 * e-mail
	 * 
	 * @param memberURI
	 *            URI of member.
	 * @param eMail
	 *            literal value.
	 */
	private void createMembersEMail(String memberURI, String eMail) {
		creator.createLiteralStatement(memberURI, HobNobVocabulary.E_MAIL_URI,
				eMail);
	}

	/**
	 * This function provide us to create member literal statement with member's
	 * surname.
	 * 
	 * @param memberURI
	 *            URI of member.
	 * @param surname
	 *            literal value.
	 */
	private void createMembersSurname(String memberURI, String surname) {

		creator.createLiteralStatement(memberURI, HobNobVocabulary.SURNAME_URI,
				surname);
	}

	/**
	 * This function provide us to create member literal statement with member's
	 * name.
	 * 
	 * @param memberURI
	 *            URI of member
	 * @param name
	 *            literal value.
	 */
	private void createMembersName(String memberURI, String name) {

		creator.createLiteralStatement(memberURI, HobNobVocabulary.NAME_URI,
				name);
	}

	/**
	 * This function provide us to create location statements and put the model
	 * that includes this created statements to the TDB store over http.
	 */
	public void putLocationStatementsToTDBOverHttp() {
		// creates seagent location statements...
		createLocationSeagentStatements();
		// creates istanbul location statements...
		createLocationIstanbulStatements();
		// creates cafe-pi location statements...
		createLocationCafePiStatements();
		// creates chios location statements...
		createLocationChiosStatements();

		accessor.add(model);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#LOCATION_CHIOS_URI} statements.
	 */
	private void createLocationChiosStatements() {

		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.LOCATION_CHIOS_URI,
				HobNobVocabulary.LOCATION_URI);
		// creates x-Coordinate literal statement...
		createXCoordinate(HobNobInstanceVocabulary.LOCATION_CHIOS_URI,
				HobNobSampleModelCreator.CHIOS_X_COORDINATE);
		// creates y-Coordinate literal statement...
		createYCoordinate(HobNobInstanceVocabulary.LOCATION_CHIOS_URI,
				HobNobSampleModelCreator.CHIOS_Y_COORDINATE);
		// creates locationHasDbpeiaInfo resource statement...
		createLocationHasDbpediaInfo(
				HobNobInstanceVocabulary.LOCATION_CHIOS_URI,
				HobNobInstanceVocabulary.CHIOS_DBPEDIA_URI);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#LOCATION_CAFE_PI_URI} statements.
	 */
	private void createLocationCafePiStatements() {

		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.LOCATION_CAFE_PI_URI,
				HobNobVocabulary.LOCATION_URI);
		// creates x-Coordinate literal statement...
		createXCoordinate(HobNobInstanceVocabulary.LOCATION_CAFE_PI_URI,
				HobNobSampleModelCreator.CAFE_PI_X_COORDINATE);
		// creates y-Coordinate literal statement...
		createYCoordinate(HobNobInstanceVocabulary.LOCATION_CAFE_PI_URI,
				HobNobSampleModelCreator.CAFE_PI_Y_COORDINATE);
		// creates locationHasDbpeiaInfo resource statement...
		createLocationHasDbpediaInfo(
				HobNobInstanceVocabulary.LOCATION_CAFE_PI_URI,
				HobNobInstanceVocabulary.IZMIR_URI);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#LOCATION_ISTANBUL_URI} statements.
	 */
	private void createLocationIstanbulStatements() {

		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.LOCATION_ISTANBUL_URI,
				HobNobVocabulary.LOCATION_URI);
		// creates x-Coordinate literal statement...
		createXCoordinate(HobNobInstanceVocabulary.LOCATION_ISTANBUL_URI,
				HobNobTDBStore.ISTANBUL_X_COORDINATE);
		// creates y-Coordinate literal statement...
		createYCoordinate(HobNobInstanceVocabulary.LOCATION_ISTANBUL_URI,
				HobNobTDBStore.ISTANBUL_Y_COORDINATE);
		// creates locationHasDbpeiaInfo resource statement...
		createLocationHasDbpediaInfo(
				HobNobInstanceVocabulary.LOCATION_ISTANBUL_URI,
				HobNobInstanceVocabulary.ISTANBUL_URI);
	}

	/**
	 * This function provide us to create
	 * {@link HobNobInstanceVocabulary#LOCATION_SEAGENT_URI} statements.
	 */
	private void createLocationSeagentStatements() {
		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.LOCATION_SEAGENT_URI,
				HobNobVocabulary.LOCATION_URI);
		// creates x-Coordinate literal statement...
		createXCoordinate(HobNobInstanceVocabulary.LOCATION_SEAGENT_URI,
				HobNobSampleModelCreator.SEAGENT_X_COORDINATE);
		// creates y-Coordinate literal statement...
		createYCoordinate(HobNobInstanceVocabulary.LOCATION_SEAGENT_URI,
				HobNobSampleModelCreator.SEAGENT_Y_COORDINATE);
		// creates locationHasDbpeiaInfo resource statement...
		createLocationHasDbpediaInfo(
				HobNobInstanceVocabulary.LOCATION_SEAGENT_URI,
				HobNobInstanceVocabulary.IZMIR_URI);
	}

	/**
	 * This function provide us to create location resource statement. It is
	 * about {@link HobNobVocabulary#LOCATION_HAS_DBPEDIA_URI}
	 * 
	 * @param locationURI
	 *            URI of location.
	 * @param dbpediaResourceURI
	 *            URI of dbpedia resource.
	 */
	private void createLocationHasDbpediaInfo(String locationURI,
			String dbpediaResourceURI) {
		creator.createResourceStatement(locationURI,
				HobNobVocabulary.LOCATION_HAS_DBPEDIA_URI, dbpediaResourceURI);
	}

	/**
	 * This function provide us to create location literal statement with
	 * location's y-Coordinate
	 * 
	 * @param locationURI
	 *            URI of location.
	 * @param yCoordinate
	 *            literal value.
	 */
	private void createYCoordinate(String locationURI, double yCoordinate) {
		creator.createLiteralStatement(locationURI,
				HobNobVocabulary.Y_COORDINATE, yCoordinate);
	}

	/**
	 * This function provide us to create location literal statement with
	 * location's x-Coordinate.
	 * 
	 * @param xCoordinate
	 *            literal value.
	 * @param locationURI
	 *            URI of location
	 */
	private void createXCoordinate(String locationURI, double xCoordinate) {
		creator.createLiteralStatement(locationURI,
				HobNobVocabulary.X_COORDINATE, xCoordinate);
	}

	/**
	 * This function provide us to create activity statements and put the model
	 * that includes this created statements to the TDB store over http.
	 */
	public void putActivityStatementsToTDBOverHttp() {

		// creates chios activity statements...
		createActivityChiosStatements();
		accessor.add(model);
	}

	/**
	 * This function provide us to create chios activity statements.
	 */
	private void createActivityChiosStatements() {
		// creates instance...
		creator.createInstance(HobNobInstanceVocabulary.ACTIVITY_CHIOS_URI,
				HobNobVocabulary.ACTIVITY_URI);
		// creates activity name literal statement...
		createActivityName(HobNobInstanceVocabulary.ACTIVITY_CHIOS_URI,
				HobNobSampleModelCreator.CHIOS_ACTIVITY_NAME);
		// creates activityAtLocation resource statement...
		createActivityAtLocation(HobNobInstanceVocabulary.ACTIVITY_CHIOS_URI,
				HobNobInstanceVocabulary.LOCATION_CHIOS_URI);
		// creates memberJoinActivity resource statement...
		createMemberJoinActivity(HobNobInstanceVocabulary.MEMBER_BAHTI_URI,
				HobNobInstanceVocabulary.ACTIVITY_CHIOS_URI);
		// creates memberJoinActivity resource statement...
		createMemberJoinActivity(HobNobInstanceVocabulary.MEMBER_CEREN_URI,
				HobNobInstanceVocabulary.ACTIVITY_CHIOS_URI);
	}

	/**
	 * This function provide us to create resource statement with using
	 * {@link HobNobVocabulary#MEMBER_JOIN_ACTIVITY_URI} property.
	 * 
	 * @param activityURI
	 *            URI of activity.
	 * @param memberURI
	 *            URI of member who joins activity.
	 */
	private void createMemberJoinActivity(String memberURI, String activityURI) {
		creator.createResourceStatement(memberURI,
				HobNobVocabulary.MEMBER_JOIN_ACTIVITY_URI, activityURI);
	}

	/**
	 * This function provide us to create resource statement with using
	 * {@link HobNobVocabulary#ACTIVITY_AT_LOCATION_URI} property.
	 * 
	 * @param activityURI
	 *            URI of activity.
	 * @param locationURI
	 *            URI of location where activity is occured.
	 */
	private void createActivityAtLocation(String activityURI, String locationURI) {
		creator.createResourceStatement(activityURI,
				HobNobVocabulary.ACTIVITY_AT_LOCATION_URI, locationURI);
	}

	/**
	 * This function provide us to create literal statement with activity's
	 * name.
	 * 
	 * @param activityURI
	 *            URI of activity.
	 * @param activityName
	 *            literal value.
	 */
	private void createActivityName(String activityURI, String activityName) {

		creator.createLiteralStatement(activityURI,
				HobNobVocabulary.ACTIVITY_NAME, activityName);
	}
}
